package org.example.server.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.tools.rmi.ObjectNotFoundException;
import org.example.common.context.BaseContext;
import org.example.common.exception.OrderStatusException;
import org.example.common.exception.RegisterException;
import org.example.common.exception.RegisterStatusException;
import org.example.common.exception.SurplusNotFoundException;
import org.example.dto.*;
import org.example.entity.*;
import org.example.server.mapper.*;
import org.example.server.service.RegisterService;
import org.example.vo.OrderVO;
import org.example.vo.RegisterDetailVO;
import org.example.vo.RegisterListVO;
import org.example.vo.RegisterVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class RegisterServiceImpl implements RegisterService {

    @Resource
    private RegisterMapper registerMapper;
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private ScheNumInfoMapper scheNumInfoMapper;
    @Resource
    private ScheduleMapper scheduleMapper;
    @Resource
    private OrgInfoMapper orgInfoMapper;
    @Resource
    private DepartmentMapper departmentMapper;
    @Resource
    private DoctorMapper doctorMapper;
    @Resource
    private PatientMapper patientMapper;



    //加锁
    //1.预约前用号源id查询是否还有余号
    @Transactional(rollbackFor = Exception.class)
    @Override
    public RegisterVO appoint(RegisterDTO registerDTO) {

        //System.out.println(count);
        //  String hospitalNo = registerDTO.getHospitalNo();

        ScheNumInfo scheNumInfo = scheNumInfoMapper.selectById(registerDTO);
        if (scheNumInfo.getSurplus() == 0) {
            log.info("余号已经没有了，请改天再来吧");
            throw new SurplusNotFoundException("余号已经没有了，请改天再来吧");
        }

        //2.预约成功后，要新建一个预约记录表，修改预约状态,建一个订单表 ，

        // Register register = registerMapper.selectByScheNumId(registerDTO.getScheNumId());

        OrgInfo orgInfo = orgInfoMapper.selectByNo(registerDTO.getHospitalNo());

        Department department = departmentMapper.selectByCode(scheNumInfo);
        DoctorInfo doctorInfo = doctorMapper.selectByCode(scheNumInfo);

        ScheduleInfo scheduleInfo1 = scheduleMapper.selectByDD(scheNumInfo.getDoctorCode(), scheNumInfo.getScheDate());
        PatientInfo patientInfo = patientMapper.selectByPatientNo(registerDTO.getPatientNo());
        String registerId = "";

        String orderId = "";
        LocalTime now = LocalTime.now();
        LocalTime startTime;
        LocalTime endTime;
        LocalDate scheDate = null;//预约日期,只能设在今天和明天，没有参数无法做更多处理
        if (now.isAfter(LocalTime.of(9, 0)) && now.isBefore(LocalTime.of(12, 0))) {
            startTime = now;
            endTime = LocalTime.of(12, 0);
            scheDate = LocalDate.now();
        } else if (now.isAfter(LocalTime.of(14, 0)) && now.isBefore(LocalTime.of(17, 0))) {
            startTime = now;
            endTime = LocalTime.of(17, 0);
            scheDate = LocalDate.now();
        } else if (now.isBefore(LocalTime.of(9, 0))) {

            startTime = LocalTime.of(9, 0);
            endTime = LocalTime.of(12, 0);
            scheDate = LocalDate.now();
        } else if (now.isAfter(LocalTime.of(17, 0))) {
            startTime = LocalTime.of(9, 0);
            endTime = LocalTime.of(12, 0);
            scheDate = LocalDate.now().plusDays(1);

        } else {
            startTime = LocalTime.of(14, 0);
            endTime = LocalTime.of(17, 0);
            scheDate = LocalDate.now();
        }

     //  PatientInfo patientInfo1 = patientMapper.selectByPatientNo(registerDTO.getPatientNo());
        if (orgInfo != null && department != null && doctorInfo != null && patientInfo != null) {
            Register register = Register.builder().
                    hospitalNo(registerDTO.getHospitalNo()).hospitalName(orgInfo.getHospitalName()).
                    deptCode(scheNumInfo.getDeptCode()).
                    deptName(department.getDepartmentName())
                    .doctorCode(scheNumInfo.getDoctorCode()).
                    doctorName(doctorInfo.getDoctorName()).
                    userId(BaseContext.getCurrentId()).
                    patientId(patientInfo.getPatientId()).
                    patientNo(registerDTO.getPatientNo()).
                    patientName(patientInfo.getPatientName()).
                    scheNumId(registerDTO.getScheNumId()).
                    scheDate(scheDate).
                    startTime(startTime).
                    endTime(endTime).
                    registerId("1").
                    scheduleId("1").
                    orderId("1").
                    registerStatus("WAIT_PAY").
                    createTime(new Date()).
                    updateTime(new Date()).
                    registerFee(BigDecimal.valueOf(40.00)).
                    build();
            registerMapper.insert(register);


            register.setRegisterId(String.valueOf(register.getId()));

            register.setScheduleId(scheduleInfo1.getScheduleId());


            Order order = Order.builder().
                    orderId("1").
                    bizId("内科业务").
                    orderAmt(register.getRegisterFee()).
                    orderStatus("WAIT_PAY").

                    createTime(new Date()).
                    updateTime(new Date()).
                    payType(registerDTO.getPayType()).
                    build();
            orderMapper.insert(order);
            order.setOrderId(String.valueOf(order.getId()));
            register.setOrderId(order.getOrderId());

            registerId = register.getRegisterId();

            orderId = register.getOrderId();
            registerMapper.updateBy(register);
            orderMapper.updateBy(order);

            //4.余号减一
            String scheduleId = register.getScheduleId();
            String scheNumId = register.getScheNumId();

            ScheduleInfo scheduleInfo = scheduleMapper.selectById(scheduleId);
            if (scheduleInfo != null) {
                Integer surplus = scheNumInfo.getSurplus();
                scheNumInfo.setSurplus(surplus - 1);

                scheNumInfoMapper.updateBy(scheNumInfo);

                scheduleInfo.setSurplus(scheduleInfo.getSurplus() - 1);
                scheduleMapper.updateBy(scheduleInfo);
            }
        }
        RegisterVO registerVO = RegisterVO.builder().
                registerId(registerId).
                orderId(orderId).
                registerStatus("WAIT_PAY").
                orderStatus("WAIT_PAY").build();


        return registerVO;

    }


    //3.支付成功后，修改支付状态

    //还有别的业务，在挂号成功的同时，要减去一个医生下边的号源的数量
    //预约完成后要更新一个订单表
    @Override
    public OrderVO order(OrderDTO orderDTO) {

        Order order = orderMapper.selectByOrderId(orderDTO.getOrderId());
        Register register = registerMapper.selectByRegisterId(orderDTO);
        OrderVO orderVO = new OrderVO();
        if (order != null && register != null) {
            order.setOrderStatus("PAIED");
            order.setOrderTime(new Date());
            order.setUpdateTime(new Date());

            try {
                orderMapper.updateBy(order);
            } catch (Exception e) {
                log.info("订单状态修改失败");
                throw new OrderStatusException("订单状态修改失败");
            }

            register.setRegisterStatus("SUCCEED");

            try {
                registerMapper.updateById(register);
            } catch (Exception e) {
                log.info("预约状态修改失败");
                throw new RegisterStatusException("预约状态修改失败");
            }
            // String doctorCode = register.getDoctorCode();


            //   orderVO.setOrderStatus("PAIED");
            BeanUtils.copyProperties(order, orderVO);

            orderVO.setRegisterId(orderDTO.getRegisterId());
        }
        return orderVO;
    }

    @Override
    public List<RegisterListVO> selectList(RegisterListDTO registerListDTO) {
        List<Register> registerList = registerMapper.selectByPatientId(registerListDTO);


        List<RegisterListVO> registerListVOS = new ArrayList<>();
        registerList.forEach(register -> {
            RegisterListVO registerListVO = new RegisterListVO();
            BeanUtils.copyProperties(register, registerListVO);
            String doctorCode = register.getDoctorCode();
            DoctorDTO doctorDTO = DoctorDTO.builder().hospitalNo(registerListDTO.getHospitalNo()).doctorCode(doctorCode).build();
            DoctorInfo doctorInfo = doctorMapper.selectByCode(doctorDTO);
            registerListVO.setAvatarImg(doctorInfo.getAvatarImg());
            registerListVO.setTitle(doctorInfo.getTitle());
            registerListVOS.add(registerListVO);


        });
        return registerListVOS;
    }


    @Override
    public RegisterDetailVO selectDetail(RegisterDetailDTO registerDetailDTO) {

        Register register = registerMapper.selectByRegisterDetail(registerDetailDTO);
        if (register == null) {
            throw new RegisterException("挂号信息不存在");
        }
        RegisterDetailVO registerDetailVO = new RegisterDetailVO();
        DoctorDTO doctorDTO = DoctorDTO.builder().
                hospitalNo(registerDetailDTO.getHospitalNo()).
                doctorCode(register.getDoctorCode()).
                deptCode(register.getDeptCode()).
                build();


        DoctorInfo doctorInfo = doctorMapper.selectByCode(doctorDTO);
        Department department = departmentMapper.selectByCode(doctorDTO);
        BeanUtils.copyProperties(register, registerDetailVO);
        if (doctorDTO != null && department != null) {


            registerDetailVO.setAvatarImg(doctorInfo.getAvatarImg());
            registerDetailVO.setTitle(doctorInfo.getTitle());
            registerDetailVO.setDeptAddress(department.getDeptAddress());

        }

        return registerDetailVO;
    }
}
